<template>
  <div class="main">
    <div :id="cid" class="item"></div>
    <el-card class="item sub">
      <div v-for="o in 4" :key="o">
        {{'图标说明 ' + o }}
      </div>
    </el-card>
  </div>
</template>

<script>
import * as d3 from 'd3';
import 'd3-selection'
import 'd3-polygon'
import 'd3-random'

export default {
  name: "VoronoiLabels",
  props:['cid','height'],
  mounted() {
    function data () {
      const randomX = d3.randomNormal(width / 2, 80);
      const randomY = d3.randomNormal(height / 2, 80);
      return d3.range(200)
          .map(() => ([randomX(), randomY()]))
          .filter(d => 0 <= d[0] && d[0] <= width && 0 <= d[1] && d[1] <= height);
    }

    let height = this.height.slice(0, -2)
    let width = 1000
    let delaunay = d3.Delaunay.from(data())
    let voronoi = delaunay.voronoi([-1, -1, width + 1, height + 1])
    let orient = ({
      top: text => text.attr("text-anchor", "middle").attr("y", -6),
      right: text => text.attr("text-anchor", "start").attr("dy", "0.35em").attr("x", 6),
      bottom: text => text.attr("text-anchor", "middle").attr("dy", "0.71em").attr("y", 6),
      left: text => text.attr("text-anchor", "end").attr("dy", "0.35em").attr("x", -6)
    })

    const svg = d3.select(`#${this.cid}`).append('svg')
        .attr("viewBox", [0, 0, width, height]);

    const cells = data().map((d, i) => [d, voronoi.cellPolygon(i)]);

    svg.append("g")
        .attr("stroke", "orange")
        .selectAll("path")
        .data(cells)
        .join("path")
        .attr("d", ([d, cell]) => `M${d3.polygonCentroid(cell)}L${d}`);

    svg.append("path")
        .attr("fill", "none")
        .attr("stroke", "#ccc")
        .attr("d", voronoi.render());

    svg.append("path")
        .attr("d", delaunay.renderPoints(null, 2));

    svg.append("g")
        .style("font", "10px sans-serif")
        .selectAll("text")
        .data(cells)
        .join("text")
        .each(function([[x, y], cell]) {
          const [cx, cy] = d3.polygonCentroid(cell);
          const angle = (Math.round(Math.atan2(cy - y, cx - x) / Math.PI * 2) + 4) % 4;
          d3.select(this).call(angle === 0 ? orient.right
              : angle === 3 ? orient.top
                  : angle === 1 ? orient.bottom
                      : orient.left);
        })
        .attr("transform", ([d]) => `translate(${d})`)
        .attr("display", ([, cell]) => -d3.polygonArea(cell) > 2000 ? null : "none")
        .text((d, i) => i);

    return svg.node();
  },
  methods:{

  }
}
</script>

<style scoped>
.main{
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: flex-end
}
.item{
  flex-grow:1;
  flex-shrink:1;
}
.sub{
  max-width: 300px;
  min-width: 200px;
  flex-grow:1;
  flex-shrink:0;
}
</style>